package cn.com.okgo;

import android.app.Application;
import android.content.Context;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import cn.com.okgo.Interceptors.CookieInterceptor;
import cn.com.okgo.cookie.CookiesManager;
import cn.com.okgo.https.HttpsUtils;
import cn.com.okgo.model.HttpHeaders;
import cn.com.okgo.model.HttpParams;
import cn.com.okgo.request.GetRequest;
import cn.com.okgo.request.PostRequest;
import okhttp3.Call;
import okhttp3.OkHttpClient;

/**
 * Created by luwenlong on 2017/8/28.
 */

public class OkGo {
    public static final int DEFAULT_SECONDS = 10;               //默认的超时时间

    private static Application context;                         //全局上下文
    private OkHttpClient okHttpClient;                          //ok请求的客户端
    private HttpParams mCommonParams;       //全局公共请求参数
    private HttpHeaders mCommonHeaders;     //全局公共请求头


    public static OkGo getInstance() {
        return OkGoHolder.holder;
    }

    private static class OkGoHolder {
        private static OkGo holder = new OkGo();
    }

    /**
     * 必须在全局Application先调用，获取context上下文，否则缓存无法使用
     */
    public static void init(Application app) {
        context = app;
    }

    /**
     * 获取全局上下文
     */
    public static Context getContext() {
        if (context == null)
            throw new IllegalStateException("请先在全局Application中调用 OkGo.init() 初始化！");
        return context;
    }


    private OkGo() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(DEFAULT_SECONDS, TimeUnit.SECONDS);
        builder.readTimeout(DEFAULT_SECONDS, TimeUnit.SECONDS);
        builder.writeTimeout(DEFAULT_SECONDS, TimeUnit.SECONDS);
        builder.cookieJar(new CookiesManager());
        //builder.addInterceptor(new CookieInterceptor());

        HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory();
        builder.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager);
        builder.hostnameVerifier(HttpsUtils.UnSafeHostnameVerifier);

        okHttpClient= builder.build();
    }


    public OkHttpClient getOkHttpClient() {
        return okHttpClient;
    }

    /**
     * 自定义 OkHttpClient
     */
    public void setOkHttpClient(OkHttpClient okHttpClient){
        this.okHttpClient=okHttpClient;
    }


    /** 获取全局公共请求参数 */
    public HttpParams getCommonParams() {
        return mCommonParams;
    }

    /** 添加全局公共请求参数 */
    public OkGo addCommonParams(HttpParams commonParams) {
        if (mCommonParams == null) mCommonParams = new HttpParams();
        mCommonParams.put(commonParams);
        return this;
    }

    /** 获取全局公共请求头 */
    public HttpHeaders getCommonHeaders() {
        return mCommonHeaders;
    }

    /** 添加全局公共请求参数 */
    public OkGo addCommonHeaders(HttpHeaders commonHeaders) {
        if (mCommonHeaders == null) mCommonHeaders = new HttpHeaders();
        mCommonHeaders.put(commonHeaders);
        return this;
    }

    /**
     * 获取全局的cookie实例
     */
    public CookiesManager getCookieJar() {
        return (CookiesManager) okHttpClient.cookieJar();
    }

    /**
     * get请求
     */
    public static GetRequest get(String url) {
        return new GetRequest(url);
    }

    /**
     * post 请求
     */
    public static PostRequest post(String url) {
        return new PostRequest(url);
    }

    /**
     * download请求
     */
    public static GetRequest download(String url) {
        return new GetRequest(url);
    }

    /**
     * 根据Tag取消请求
     */
    public void cancelTag(Object tag) {
        for (Call call : getOkHttpClient().dispatcher().queuedCalls()) {
            if (tag.equals(call.request().tag())) {
                call.cancel();
            }
        }
        for (Call call : getOkHttpClient().dispatcher().runningCalls()) {
            if (tag.equals(call.request().tag())) {
                call.cancel();
            }
        }
    }

    /**
     * 取消所有请求请求
     */
    public void cancelAll() {
        for (Call call : getOkHttpClient().dispatcher().queuedCalls()) {
            call.cancel();
        }
        for (Call call : getOkHttpClient().dispatcher().runningCalls()) {
            call.cancel();
        }
    }

    private List<Object> tags() {
        List<Object> tags = new ArrayList<>();
        for (Call call : getOkHttpClient().dispatcher().queuedCalls()) {
            tags.add(call.request().tag());
        }
        for (Call call : getOkHttpClient().dispatcher().runningCalls()) {
            tags.add(call.request().tag());
        }
        return tags;
    }

    public boolean isRunning(String tag) {
        return tags().contains(tag);
    }
}
